{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Median Blur\n",
    "import cv2\n",
    "import numba\n",
    "import numpy as np\n",
    "from numba import jit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def PaddingReplica(img, num = 1):\n",
    "    if num < 1:\n",
    "        return None\n",
    "    tmp_array = img\n",
    "    tmp_array = np.insert(tmp_array, 0, values=[tmp_array[:,0]]*num, axis=1)\n",
    "    tmp_array = np.insert(tmp_array, -1, values=[tmp_array[:,-1]]*num, axis=1)\n",
    "    tmp_array = np.insert(tmp_array, 0, values=[tmp_array[0,:]]*num, axis=0)\n",
    "    tmp_array = np.insert(tmp_array, -1, values=[tmp_array[-1,:]]*num, axis=0)\n",
    "    return tmp_array\n",
    "\n",
    "# alist = [[1,2,3,4,5,6],\n",
    "#          [ 9,10,11,12,13,14],\n",
    "#          [17,18,19,20,21,22],\n",
    "#          [25,26,27,28,29,30],\n",
    "#          [33,34,35,36,37,38],\n",
    "#          [41,42,43,44,45,46],\n",
    "#         ]\n",
    "# array=np.array(alist)\n",
    "# print(PaddingReplica(array,3))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def PaddingZero(img, num = 1):\n",
    "    tmp_array = img\n",
    "    if num < 1:\n",
    "        return None\n",
    "#     print(np.zeros((len(img), num)))\n",
    "#     print(np.zeros((num, len(img) + 2 * num)))\n",
    "    tmp_array = np.insert(tmp_array, 0, values = [np.zeros(len(img))]*num, axis=1)\n",
    "    tmp_array = np.append(tmp_array, values = np.zeros((len(img), num)), axis=1)\n",
    "    tmp_array = np.insert(tmp_array, 0, values = [np.zeros(len(img) + 2 * num)]*num, axis=0)\n",
    "    tmp_array = np.append(tmp_array, values = np.zeros((num, len(img) + 2 * num)), axis=0)\n",
    "    return tmp_array.astype(\"uint8\")\n",
    "\n",
    "# alist = [[1,2,3,4,5,6],\n",
    "#          [ 9,10,11,12,13,14],\n",
    "#          [17,18,19,20,21,22],\n",
    "#          [25,26,27,28,29,30],\n",
    "#          [33,34,35,36,37,38],\n",
    "#          [41,42,43,44,45,46],\n",
    "#         ]\n",
    "# array=np.array(alist)\n",
    "# print(PaddingZero(array,5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def SelectionSort(data_list = None):\n",
    "    blist = data_list[:]\n",
    "    N = len(blist)\n",
    "    for i in range(0, N - 1):\n",
    "        min = i\n",
    "        for j in range(i + 1, N):\n",
    "            if blist[j] < blist[min]:\n",
    "                min = j\n",
    "        if min <> i:\n",
    "            blist[i], blist[min] = blist[min], blist[i]\n",
    "    return blist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def FindMediumValue(data_list):\n",
    "    tmp_list = SelectionSort(data_list)\n",
    "    #print(tmp_list)\n",
    "    if len(data_list) % 2 == 0: \n",
    "        medium_value = (tmp_list[len(data_list) / 2] + tmp_list[(len(data_list) / 2) - 1]) / 2.0\n",
    "    else:\n",
    "        medium_value = tmp_list[len(data_list) / 2]\n",
    "    return medium_value\n",
    "#alist = [1,8,3,4,5,6,7,2,5,6,75,8,8,5,8,9,0,4,3,3,2]\n",
    "#print FindMediumValue(alist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def SlidingWindow(img,padding_img, kernel_x): #kernel_x kernel x asix length\n",
    "    result = np.zeros(img.shape)\n",
    "    for padding_img_y in range(0, len(padding_img) - kernel_x + 1):\n",
    "        for padding_img_x in range(0, len(padding_img[0]) - kernel_x + 1):\n",
    "            kernel_list = []\n",
    "            for i in range(0,kernel_x):\n",
    "                for j in range(0,kernel_x):\n",
    "                    #print \"padding_img_x = %d , padding_img_y = %d \" % ((padding_img_x + i),(padding_img_y + j))\n",
    "                    kernel_list.append(padding_img[padding_img_y + i][padding_img_x + j])\n",
    "            result[padding_img_y][padding_img_x] = FindMediumValue(kernel_list)\n",
    "    return result.astype(\"uint8\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def MedianBlur(img, kernel_size, padding_way):\n",
    "    padding_num = (kernel_size - 1) / 2\n",
    "    if padding_way == 'REPLICA':\n",
    "        padding_img = PaddingReplica(img, padding_num)\n",
    "    elif padding_way == 'ZERO':\n",
    "        padding_img = PaddingZero(img, padding_num)\n",
    "    #print(padding_img)\n",
    "    #print \"x = %d , y = %d \" % (len(padding_img[0]),len(padding_img))\n",
    "    output = SlidingWindow(img, padding_img, kernel_size)\n",
    "    return output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# alist = [[1,2,3,4,5,6,100],\n",
    "#          [ 9,10,11,12,13,14,100],\n",
    "#          [17,18,19,20,21,22,100],\n",
    "#          [25,26,27,28,29,30,100],\n",
    "#          [33,34,35,36,37,38,100],\n",
    "#          [41,42,43,44,45,46,100],\n",
    "#         ]\n",
    "# res = medianBlur(alist, 3, 'ZERO')\n",
    "# print('result ======')\n",
    "# print(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(359L, 359L)\n"
     ]
    }
   ],
   "source": [
    "# Test ZERO\n",
    "img = cv2.imread('./img/origin.png')\n",
    "b, g, r = cv2.split(img)\n",
    "cv2.imshow('origin',img)\n",
    "print(b.shape)\n",
    "out_b = MedianBlur(b,5,'ZERO')\n",
    "out_g = MedianBlur(g,5,'ZERO')\n",
    "out_r = MedianBlur(r,5,'ZERO')\n",
    "merged = cv2.merge([out_b,out_g,out_r])\n",
    "cv2.imshow('out_img',merged)\n",
    "key = cv2.waitKey()\n",
    "if key == 27:\n",
    "    cv2.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(359L, 359L)\n"
     ]
    }
   ],
   "source": [
    "# Test REPLICA\n",
    "# img = cv2.imread('./img/origin.png')\n",
    "# b, g, r = cv2.split(img)\n",
    "# cv2.imshow('origin',img)\n",
    "# print(b.shape)\n",
    "# out_b = MedianBlur(b,5,'REPLICA')\n",
    "# out_g = MedianBlur(g,5,'REPLICA')\n",
    "# out_r = MedianBlur(r,5,'REPLICA')\n",
    "# merged = cv2.merge([out_b,out_g,out_r])\n",
    "# cv2.imshow('out_img',merged)\n",
    "# key = cv2.waitKey()\n",
    "# if key == 27:\n",
    "#     cv2.destroyAllWindows()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
